<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Steering Behaviours: SEEK</title>

    <script src="../libs/dat.gui.min.js"></script>
    <script src="../libs/stats.min.js"></script>
    <script src="../libs/three.min.js"></script>
    <script src="../js/threejs/controls/OrbitControls.js"></script>
    <script src="../js/ThreeSteer.js"></script>
    <link rel="stylesheet" type="text/css" href="css/main.css" />
    <link rel="stylesheet" type="text/css" href="css/gui.css" />
  </head>
  <script>
    var container;
    var camera;

    var scene, renderer;
    var controls;
    var stats;
    var entity;
    var ball;
    var boundaries;
    var params;

    function onMouseMove(event) {
      var mouse3D = new THREE.Vector3(
        (event.clientX / window.innerWidth) * 2 - 1,
        -(event.clientY / window.innerHeight) * 2 + 1,
        0
      );
      var raycaster = new THREE.Raycaster();
      raycaster.setFromCamera(mouse3D, camera);
      var intersects = raycaster.intersectObjects(scene.children);
      if (intersects.length > 0) {
        ball.position.set(intersects[0].point.x, 50, intersects[0].point.z);
      }
    }

    function init(element) {
      container = document.getElementById(element);
      camera = new THREE.PerspectiveCamera(
        45,
        window.innerWidth / window.innerHeight,
        1,
        50000
      );
      scene = new THREE.Scene();

      renderer = new THREE.WebGLRenderer({ alpha: true });
      renderer.setClearColor(0x333333, 0);
      renderer.setSize(window.innerWidth, window.innerHeight);
      renderer.domElement.style.position = "absolute";
      renderer.domElement.style.top = 0;
      container.appendChild(renderer.domElement);

      camera.position.set(0, 10000, 10000);
      camera.lookAt(new THREE.Vector3(0, 0, 0));

      controls = new THREE.OrbitControls(camera, renderer.domElement);
      controls.maxPolarAngle = Math.PI * 0.5;
      controls.minDistance = 100;
      controls.maxDistance = 30000;

      stats = new Stats();
      stats.domElement.style.position = "absolute";
      stats.domElement.style.bottom = "0px";
      stats.domElement.style.left = "180px";
      stats.domElement.style.zIndex = 100;
      container.appendChild(stats.domElement);

      // Floor
      var floorGeometry = new THREE.PlaneGeometry(10000, 10000, 32);
      var floorMaterial = new THREE.MeshBasicMaterial({
        color: 0x666666,
        transparent: true,
        opacity: 0.5,
      });
      var floor = new THREE.Mesh(floorGeometry, floorMaterial);
      floor.rotation.x = -Math.PI * 0.5;
      scene.add(floor);

      //Ball
      var ballGeometry = new THREE.SphereGeometry(50, 32, 32);
      var ballMaterial = new THREE.MeshBasicMaterial({ color: 0xbcff00 });
      ball = new THREE.Mesh(ballGeometry, ballMaterial);
      ball.position.set(
        Math.random() * (5000 - -5000) + -5000,
        50,
        Math.random() * (5000 - -5000) + -5000
      );
      scene.add(ball);

      // Entity Mesh
      var geometry = new THREE.BoxGeometry(100, 200, 50);
      var material = new THREE.MeshBasicMaterial({
        color: 0xffffff,
        wireframe: true,
      });
      var mesh = new THREE.Mesh(geometry, material);
      mesh.position.setY(100);

      // Entity
      entity = new SteeringEntity(1, mesh);
      entity.position.set(
        Math.random() * (5000 - -5000) + -5000,
        0,
        Math.random() * (5000 - -5000) + -5000
      );
      entity.lookAtDirection = true;

      scene.add(entity);

      //Plane boundaries (do not cross)
      boundaries = new THREE.Box3(
        new THREE.Vector3(-5000, 0, -5000),
        new THREE.Vector3(5000, 0, 5000)
      );

      //Gui
      var gui = new dat.GUI();

      gui.add(entity, "maxSpeed", 1, 50).name("Max Speed").step(1);
      gui.add(entity, "maxForce", 1, 20).name("Max Force").step(1);
      gui.add(entity, "lookAtDirection").name("Look At Direction");

      window.addEventListener("resize", onWindowResize, false);
      document.addEventListener("mousemove", onMouseMove, true);
      animate();
    }

    function onWindowResize() {
      camera.aspect = window.innerWidth / window.innerHeight;
      camera.updateProjectionMatrix();
      renderer.setSize(window.innerWidth, window.innerHeight);
    }

    function animate() {
      requestAnimationFrame(animate);
      controls.update();
      if (entity.position.distanceTo(ball.position) > 100) {
        entity.seek(ball.position);
        if (entity.lookAtDirection) entity.lookWhereGoing(true);
        else entity.rotation.set(0, 0, 0);
      } else {
        entity.idle();
        if (entity.lookAtDirection)
          entity.lookAt(
            new THREE.Vector3(
              ball.position.x,
              entity.position.y,
              ball.position.z
            )
          );
        else entity.rotation.set(0, 0, 0);
      }

      entity.bounce(boundaries);
      entity.update();
      renderer.render(scene, camera);
      stats.update();
    }
  </script>

  <body onload="init('container')">
    <div id="container"></div>
    <div id="msg">
      <span style="color: #bfff00; font-weight: bold">SEEK:</span><br />Move
      mouse on the floor to change ball position.
    </div>
    <a
      href="https://github.com/erosmarcon/three-steer/blob/master/examples/Seek.html"
      target="_blank"
      ><div class="view-source">View source</div></a
    >
  </body>
</html>
